package gdr.connection;

import java.io.*;
import java.net.*;

/**
 * Costruisce la connessione client/server lato client
 * @author Giorgio Vitale
 *
 */
public class Client implements Runnable{
	protected String host;
	protected int port;
	protected String username;
	
	protected ClientManager manager;
	protected Socket socket;
	protected Thread clientThread;
	protected ObjectOutputStream oos;
	protected ObjectInputStream ois;
	protected boolean stop;
	
	
	public Client(String host, int port, String username){
		this.host = host;
		this.port = port;
		this.username = username;
		stop = false;
		try{
			socket = new Socket(host, port);
			oos = new ObjectOutputStream(socket.getOutputStream());
			ois = new ObjectInputStream(socket.getInputStream());
		}
		catch (Exception e){ stopClient();}	
	}
	/**
	 * Avvia il thread
	 */
	public void start(){
		if (clientThread!=null) return;
		clientThread = (new Thread(this));
		clientThread.start();
	}
	
	public void run(){
		try{
			System.out.println("apertura connessione riuscita");
		} catch (Exception e) {
			System.out.println("errore connessione");
			e.printStackTrace(); 
			stopClient();
		}
	}
	/**
	 * Chiude la coonnessione
	 */
	public void stopClient(){
		System.out.println("chiudo connessione");
		if (stop) return;
		stop = true;
		try{
			ois.close();
			oos.close();
			socket.close();
		} catch (Exception e) { oos=null; ois=null; socket=null;}
	}
	/**
	 * Invia un messaggio al server
	 * @param o
	 * @throws ChannelException
	 */
	public void sendMessage(Object o) throws ChannelException{
		if (stop) throw new ChannelException();
		System.out.println("manda messaggio");
		try{oos.writeObject(o);
		} catch(Exception e)
		{	System.out.println("errore invio messaggio");
			e.printStackTrace(); 
			stopClient();
			throw new ChannelException();
		}
	}
	/**
	 * Riceve un messaggio dal server
	 * @return
	 * @throws ChannelException
	 */
	public Object receiveMessage() throws ChannelException{
		if (stop) throw new ChannelException();
		System.out.println("riceve messaggio");
		try{	return ois.readObject();
		} catch(Exception e)
		{	System.out.println("errore ricezione messaggio");
			e.printStackTrace(); 
			stopClient();
			throw new ChannelException();
		}
	}
	
	public void setManager(ClientManager manager) {
		this.manager = manager;
	}
	
	public static void create(String[] arg){
		Client c = new Client("localhost",20000,arg[0]);
		ClientManager m = new ClientManager();
		c.setManager(m);
		m.setClient(c);
		(new Thread(m)).start();
		c.start();
	}
}